#ifndef GENERATOR_H
#define GENERATOR_H

#include <string>
#include <vector>

namespace physical
{
/**
  * class generator
  * Represents a single generator of any type. This includes the following (if
  * applicable): heat source, turbine, energy gathering device, etc.
  */

class generator
{
public:         // Constructors/Destructors

    /**
     * Empty Constructor
     */
    generator ( );

    /**
     * Constructor
     * @param  production_curve List of production curve constants from equ. form:
     * [1]+[2]*P^2+[3]*P^3+[4]*P^4+[5]*P^5+...
     * @param  min_pwr minimum operational output power of generator.
     * @param  max_pwr maximum operational output power of generator.
     * @param  min_up_time minimum operatin time of generator.
     * @param  min_down_time minimum resting time of generator before started again.
     * @param  startup_cost monetary value to start the generator.
     */
    generator (int order = 0, float* production_curve = NULL, float min_pwr = -1.00, float max_pwr = -1.00,
               float min_up_time = -1.00, float min_down_time = -1.00, float startup_cost = -1.00 );

    /**
     * Empty Destructor
     */
    virtual ~generator ( );



public:         // Public general methods

    /**
     * Returns how much input it will take for the generator to meet the load.
     * @return double
     * @param  load
     */
    double loadCost (float load );

    /**
     * Changes the generator status and returns the set status. If current status is
     * "ON", then function begins shutdown sequence and returns FALSE (OFF). If current
     * status is "OFF", then function begins startup sequence and returns TRUE (ON).
     * @return bool
     */
    bool switchGenStatus ( );

    /**
     * Begins generator startup sequence and returns TRUE if commencement of startup is
     * successful, else returns FALSE. If generator is already running, returns TRUE.
     * @return bool
     */
    bool setGenOn ( );

    /**
     * Begins generator shutdown sequence and returns TRUE if commencement of shutdown
     * is successful, else returns FALSE. If generator is already resting, returns TRUE.
     * @return bool
     */
    bool setGenOff ( );

    /**
     * Returns the operating status of the generator.
     * @return bool
     */
    bool getGenStat ( );

    /**
     * Returns current output of the generator.
     * @return double
     */
    double getGenOutput( );

    /**
     * Schedule the generator to a certian power output.
     * Returns true if successful, else false (i.e. out of range)
     * @return bool
     * @param  load
     */
    bool scheduleGen( double load );

    /**
     * Returns minimum operating power output of the generator.
     * @return float
     */
    float minPowerOutput( );

    /**
     * Returns maximum operating power output of the generator.
     * @return float
     */
    float maxPowerOutput( );

    /**
     * Return order of production curve equation.
     * @return int
     */
    int getOrder( );

    /**
     * Returns pointer to array of production curve equation constants.
     * @return float pointer
     */
    float* getCurve( );

    /**
     * Returns pointer to array of incremental production curve equation constants.
     * @return float pointer
     */
    float* getIncrementalCurve( );

    /**
     * This overloads the standard == operator for this specific class.
     * @param rhs reference pointer to generator object
     * @return bool
     */
    bool operator== (const generator &rhs);


private:        // Private attribute accessor methods

    /**
     * Set the value of numProdConst
     * @param new_var the new value of numProdConst
     */
    void setNumProdConst ( int new_var );

    /**
     * Get the value of numProdConst
     * @return int
     */
    int getNumProdConst ( );

    /**
     * Set the value of prodCurve
     * @param new_var the new value of prodCurve
     */
    void setProdCurve ( float* new_var );

    /**
     * Get the value of prodCurve
     * @return the value of prodCurve
     */
    float* getProdCurve ( );

    /**
     * Set the value of prodIncCurve
     * @param new_var the new value of prodIncCurve
     */
    void setProdIncCurve ( float* new_var );

    /**
     * Get the value of prodIncCurve
     * @return the value of prodIncCurve
     */
    float* getProdIncCurve ( );

    /**
     * Set the value of minPwr
     * Minimum power output for the generator.
     * @param new_var the new value of minPwr
     */
    void setMinPwr ( float new_var );

    /**
     * Get the value of minPwr
     * Minimum power output for the generator.
     * @return the value of minPwr
     */
    float getMinPwr ( );

    /**
     * Set the value of maxPwr
     * Maximum power output of the generator.
     * @param new_var the new value of maxPwr
     */
    void setMaxPwr ( float new_var );

    /**
     * Get the value of maxPwr
     * Maximum power output of the generator.
     * @return the value of maxPwr
     */
    float getMaxPwr ( );

    /**
     * Set the value of minUpTime
     * Minimum time running at operational conditions before the generator can be
     * shutdown.
     * @param new_var the new value of minUpTime
     */
    void setMinUpTime ( float new_var );

    /**
     * Get the value of minUpTime
     * Minimum time running at operational conditions before the generator can be
     * shutdown.
     * @return the value of minUpTime
     */
    float getMinUpTime ( );

    /**
     * Set the value of minDownTime
     * Minimum time after shutdown before the generator can begin startup sequence.
     * @param new_var the new value of minDownTime
     */
    void setMinDownTime ( int new_var );

    /**
     * Get the value of minDownTime
     * Minimum time after shutdown before the generator can begin startup sequence.
     * @return the value of minDownTime
     */
    int getMinDownTime ( );

    /**
     * Set the value of startupCost
     * The monetary cost to bring the generator to operating conditions.
     * @param new_var the new value of startupCost
     */
    void setStartupCost ( float new_var );

    /**
     * Get the value of startupCost
     * The monetary cost to bring the generator to operating conditions.
     * @return the value of startupCost
     */
    float getStartupCost ( );

    /**
     * Set the value of isOperating
     * The operating status of the generator: TRUE = outputing power, FALSE = not
     * opperating
     * @param new_var the new value of isOperating
     */
    void setIsOperating ( bool new_var );

    /**
     * Get the value of isOperating
     * The operating status of the generator: TRUE = outputing power, FALSE = not
     * opperating
     * @return the value of isOperating
     */
    bool getIsOperating ( );

    /**
     * Set the value of electoutput
     * Current electrical output of generator.
     * @param new_var the new value of electoutput
     */
    void setElectoutput ( double new_var );

    /**
     * Get the value of electoutput
     * Current electrical output of generator.
     * @return the value of electoutput
     */
    double getElectoutput ( );


private:        // Other private functions

    /**
     * Initialization function of class variables.
     */
    void initAttributes ( ) ;

private:        // Static Private attributes
private:        // Private attributes

    int numProdConst;   // Order of the production curve from form:
                        //  [1] + [2]*P^1 + [3]*P^2 + [4]*P^3 + [5]*P^4 + [6]*P^5...
    float* prodCurve;   // Ptr to probuction curve constants from form:
                        //  [1] + [2]*P^1 + [3]*P^2 + [4]*P^3 + [5]*P^4 + [6]*P^5...
    float* prodIncCurve;// Ptr to incremental probuction curve constants from form:
                        //  [2] + 2*[3]*P^1 + 3*[4]*P^2 + 4*[5]*P^3 + 5*[6]*P^4...
    float minPwr;       // Minimum power output for the generator.
    float maxPwr;       // Maximum power output of the generator.
    float minUpTime;    // Minimum time running at operational conditions before the generator can be shutdown.
    int minDownTime;    // Minimum time after shutdown before the generator can begin startup sequence.
    float startupCost;  // The monetary cost to bring the generator to operating conditions.
    bool isOperating;   // The operating status of the generator: TRUE = outputing power, FALSE = not opperating.
    double electoutput; // Current electrical output of generator.

};

}; // end namespace physical
#endif // GENERATOR_H
